#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#继承
#system 自动继承object类 所以可以省略
class Animal(object):
    can = 'breath'

    def run(self):
        print('animal is running')


class Cat(Animal):
    pass


class Dog(Animal):
    
    def run(self):
        print('dog is running')

    def eat(self):
        print('dog like eat')

cat = Cat()
cat.run()

dog = Dog()
dog.run()
dog.eat()

animal = Animal()

#多态
#dog 不仅是 Dog的实例 同时也是 Animal的实例
print(isinstance(dog, Dog))
print(isinstance(animal, Animal))
print(isinstance(dog, Animal))


#多态的好处
def run_twice(obj):
    obj.run()
    obj.run()

run_twice(Animal())

run_twice(Dog())

#传入的任意类型，只要是Animal类或者子类，就会自动调用实际类型的run()方法，这就是多态的意思。
#调用方只管调用，不管细节，而当我们新增一种Animal的子类时，只要确保run()方法编写正确，不用管原来的代码是如何调用的。这就是著名的“开闭”原则：
#对扩展开放：允许新增Animal子类；
#对修改封闭：不需要修改依赖Animal类型的run_twice()等函数。

#获得一个对象的所有属性和方法
print(dir(Animal))

#hasattr setattr getattr
print(hasattr(Animal, 'can'))
print(setattr(Animal, 'like', 'eat'))
print(getattr(Animal, 'like'))